﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Net;
using System.Collections;
using WeChatLibrary.CheckSignUtility;
using WeChatLibrary.GetMsgServer;
using WeChat.Core.ExtraCore;
using WeChat.Core.Common;
using WeChat.Core.MsgCore;
using System.Configuration;
using System.Xml;
using SF.Ucenter.shallWeChat;
using SF;
using System.Data;


namespace SF.Ucenter
{
    public partial class AutoResponse : System.Web.UI.Page
    {
        string code_uri, openid_uri, user_uri, appid, secret, inf_uri, info_uri, temp_uri, qrcode_uri, sendmsg_uri;
        SF.Ucenter.api.wxpay.WebClient obj = new SF.Ucenter.api.wxpay.WebClient();
        protected void Page_Load(object sender, EventArgs e)
        {
            //参考接口文档，需要用户服务器配置的响应地址，端口为80端口，接收用户发过的数据[称为被动响应]
            #region 被动响应
            if (!IsPostBack)
            {
                //string echostr1 = Request["echostr"].ToString();
                //WriteTxt("ECHOSTR:" + echostr1 );

                IDictionary dict = ConfigurationManager.GetSection("weixinPay") as IDictionary;
                string postStr = "";
                string Token = dict["WeixinToken"].ToString(); //与微信平台那边填写的token一致

                code_uri = dict["code_uri"].ToString();                 //"https://open.weixin.qq.com/connect/oauth2/authorize?"
                openid_uri = dict["openid_uri"].ToString();             //"https://api.weixin.qq.com/sns/oauth2/access_token?"
                user_uri = dict["user_uri"].ToString();                 //"https://api.weixin.qq.com/sns/userinfo?"
                appid = dict["appid"].ToString();                       //"wxa9b8e33e48ac5e0f"
                secret = dict["appsecret"].ToString();                  //"1c25328d0f3d9fbd8a65a88794828eee"
                inf_uri = dict["inf_uri"].ToString();                   //"https://api.weixin.qq.com/cgi-bin/token?"
                info_uri = dict["info_uri"].ToString();                 //"https://api.weixin.qq.com/cgi-bin/token?"
                temp_uri = dict["temp_uri"].ToString();                 //"https://api.weixin.qq.com/cgi-bin/qrcode/create?"
                qrcode_uri = dict["qrcode_uri"].ToString();             //"https://mp.weixin.qq.com/cgi-bin/showqrcode?"
                sendmsg_uri = dict["sendmsg_uri"].ToString();           //"https://api.weixin.qq.com/cgi-bin/message/custom/send"

                if (Request.HttpMethod.ToLower() == "get")
                {
                    #region 首次绑定使用
                    // 微信加密签名
                    string signature = Request.QueryString["signature"];
                    // 时间戳
                    string timestamp = Request.QueryString["timestamp"];
                    // 随机数
                    string nonce = Request.QueryString["nonce"];
                    // 随机字符串
                    string echostr = Request.QueryString["echostr"];
                    //if (Token.CheckSignature(signature, timestamp, nonce))
                    if (!string.IsNullOrEmpty(echostr))
                    {
                        Response.Clear();
                        Response.ContentType = "text/plain";
                        Response.Write(echostr);
                        Response.End();
                    }
                    #endregion
                }
                else if (Request.HttpMethod.ToLower() == "post")
                {
                    try
                    {
                        #region
                        Stream s = System.Web.HttpContext.Current.Request.InputStream;
                        byte[] b = new byte[s.Length];
                        s.Read(b, 0, (int)s.Length);
                        postStr = Encoding.UTF8.GetString(b);

                        if (!string.IsNullOrEmpty(postStr))
                        {
                            //封装请求类
                            XmlDocument doc = new XmlDocument();
                            doc.LoadXml(postStr);
                            XmlElement rootElement = doc.DocumentElement;

                            XmlNode MsgType = rootElement.SelectSingleNode("MsgType");

                            WeiXinRequest requestXML = new WeiXinRequest();
                            requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
                            requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
                            requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
                            requestXML.MsgType = MsgType.InnerText;

                            if (requestXML.MsgType == "text")
                            {
                                requestXML.Content = rootElement.SelectSingleNode("Content").InnerText;
                                requestXML.MsgId = rootElement.SelectSingleNode("MsgId").InnerText;
                            }
                            else if (requestXML.MsgType == "location")
                            {
                                requestXML.Location_X = rootElement.SelectSingleNode("Location_X").InnerText;
                                requestXML.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText;
                                requestXML.Scale = rootElement.SelectSingleNode("Scale").InnerText;
                                requestXML.Label = rootElement.SelectSingleNode("Label").InnerText;
                            }
                            else if (requestXML.MsgType == "image")
                            {
                                requestXML.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
                            }
                            else if (requestXML.MsgType == "event")
                            {
                                requestXML.Wxevent = rootElement.SelectSingleNode("Event").InnerText;
                                requestXML.EventKey = rootElement.SelectSingleNode("EventKey").InnerText;
                            }
                            else if (requestXML.MsgType == "voice")
                            {
                                requestXML.Recognition = rootElement.SelectSingleNode("Recognition").InnerText;
                            }
                            //WriteTxt("----------粉丝发送过来的消息，消息类型：" + requestXML.MsgType + "----------：" + postStr);
                            //回复消息
                            ResponseMsg(requestXML);
                        }
                        #endregion
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            #endregion
        }

        #region 被动响应
        /// <summary>
        /// 回复消息(微信信息返回)
        /// </summary>
        /// <param name="weixinXML"></param>
        private void ResponseMsg(WeiXinRequest requestXML)
        {
            WriteTxt("进入方法ResponseMsg");
            string resxml = "<xml><ToUserName><![CDATA[" + requestXML.FromUserName + "]]></ToUserName><FromUserName><![CDATA[" + requestXML.ToUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime>";
            try
            {
                if (requestXML.MsgType == "text")
                {
                    #region 用户输入文本关键字，反馈 商户设置的对应图文或文本信息
                    IDictionary dict = ConfigurationManager.GetSection("weixinPay") as IDictionary;
                    string uri = dict["ip_url"].ToString();
                    Model.sf_appidmanage appModel = new BLL.sf_appidmanage().GetModelByNum(requestXML.ToUserName);
                    string reqs = "";
                    //先匹配图文回复 无匹配采用文本回复
                    DataTable dts = new BLL.sf_reply_imgs().GetList("busnieseNum='" + appModel.businessNum + "' and appNum='"+appModel.appid+"' ").Tables[0];
                    foreach (DataRow r in dts.Rows)
                    {
                        if (r["matchModel"].ToString().Equals("1") && requestXML.Content.Equals(r["keywords"].ToString()))
                        {
                            reqs = "<item><Title><![CDATA[" + requestXML.Content + "]]></Title><Description><![CDATA[" + r["replyMsg"].ToString() + "]]></Description><PicUrl><![CDATA[" + uri + r["replyImg"].ToString() + "]]></PicUrl><Url><![CDATA[]]></Url></item>";
                        }
                        else if (r["matchModel"].ToString().Equals("0") && requestXML.Content.IndexOf(r["keywords"].ToString()) >= 0)
                        {
                            if (reqs.Equals(""))
                            {
                                reqs = "<item><Title><![CDATA[" + requestXML.Content + "]]></Title><Description><![CDATA[" + r["replyMsg"].ToString() + "]]></Description><PicUrl><![CDATA[" + uri + r["replyImg"].ToString() + "]]></PicUrl><Url><![CDATA[]]></Url></item>";
                            }
                        }
                    }
                    if (reqs.Equals(""))
                    {
                        DataTable dtg = new BLL.sf_reply_text().GetList("busnieseNum='" + appModel.businessNum + "' and appNum='" + appModel.appid + "' ").Tables[0];
                        foreach (DataRow r in dtg.Rows)
                        {
                            if (r["matchModel"].ToString().Equals("1") && requestXML.Content.Equals(r["keywords"].ToString()))
                            {
                                reqs = "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + r["replyMsg"].ToString() + "]]></Content>";
                            }
                            else if (r["matchModel"].ToString().Equals("0") && requestXML.Content.IndexOf(r["keywords"].ToString()) >= 0)
                            {
                                if (reqs.Equals(""))
                                {
                                    reqs = "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + r["replyMsg"].ToString() + "]]></Content>";
                                }
                            }
                        }
                        if (reqs.Equals(""))
                        {
                            reqs = "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[输入内容未设置反馈信息！]]></Content>";
                        }
                    }
                    else
                    {
                        reqs = "<MsgType><![CDATA[news]]></MsgType><ArticleCount>" + 1 + "</ArticleCount><Articles>" + reqs + "</Articles>";
                    }

                    resxml += reqs+"<FuncFlag>0</FuncFlag></xml>";
                    #endregion
                }
                else if (requestXML.MsgType == "location")
                {
                    resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你发过来的是地理消息\n哈哈]]></Content><FuncFlag>0</FuncFlag></xml>";
                }
                else if (requestXML.MsgType == "voice")
                {
                    if (requestXML.Recognition == "公文")
                    {
                        resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[这是微信OA中您的公文]]></Content><FuncFlag>0</FuncFlag></xml>";
                    }
                    //resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + requestXML.Recognition + "]]></Content><FuncFlag>0</FuncFlag></xml>";
                }
                else if (requestXML.MsgType == "image")
                {
                    resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你发一张图片过来我怎么识别啊，你以为我有眼睛啊\n哈哈]]></Content><FuncFlag>0</FuncFlag></xml>";
                }
                else if (requestXML.MsgType == "event")
                {
                    if (requestXML.Wxevent == "unsubscribe")
                    {
                        #region 取消关注 变更关注状态
                        //更改 用户 关注状态 isAttention
                        BLL.sf_user_info userBLl = new BLL.sf_user_info();
                        Model.sf_user_info userInfo = new Model.sf_user_info();
                        userInfo = userBLl.GetModelByOpenId(requestXML.FromUserName);
                        userInfo.isAttention = 1;
                        userBLl.Update(userInfo);
                        #endregion
                    }
                    else
                    {
                        if (requestXML.Wxevent == "CLICK")
                        {
                            //获取 二维码 响应
                            if (requestXML.EventKey == "getqrcodeimg")
                            {
                                try
                                {
                                    #region 获取每个用户的 含有二维码的推广图片
                                    BLL.sf_user_info userBll = new BLL.sf_user_info();
                                    //根据获取到的 openid 得到当前用户对象
                                    Model.sf_user_info userInfo = userBll.GetModelByOpenId(requestXML.FromUserName);
                                    string businessNum = "", appNum = appid, appSecret = secret, appWhere="";
                                    if (userInfo != null)
                                    {
                                        businessNum = userInfo.busnieseNum;
                                        appNum = userInfo.appNum;
                                        appSecret = new BLL.sf_appidmanage().GetModel(userInfo.appNum).appsecret;
                                        appWhere = Common.Utils.getWhereByInfo(businessNum, appNum, userInfo.templatesNum);
                                    }
                                    //获取微信接口的access_token
                                    string str3 = obj.GetHtml(inf_uri + "grant_type=client_credential&appid=" + appNum + "&secret=" + appSecret);
                                    wxaccesstoken ak = api.wxpay.JsonHelper.JsonDeserialize<wxaccesstoken>(str3);

                                    //获取 二维码 对象  用于换取 二维码资源 链接
                                    string str4 = obj.Post(temp_uri + "access_token=" + ak.access_token, "{\"action_name\": \"QR_LIMIT_STR_SCENE\", \"action_info\": {\"scene\": {\"scene_str\": \"" + userInfo.inviteKey + "\"}}}");
                                    shallWeChat.qrcode qr = api.wxpay.JsonHelper.JsonDeserialize<shallWeChat.qrcode>(str4);

                                    /*通过ticket换二维码*/
                                    string imgs = Server.UrlEncode(qr.ticket);
                                    obj.DownloadFile(qrcode_uri + "ticket=" + imgs, Common.Utils.GetMapPath("/allqrcode/code/" + userInfo.inviteKey + ".jpg"));
                                    //生成推广图片 并 返回图片 相对路径
                                    allqrcode.QrCode qrcode = new allqrcode.QrCode();
                                    string imguri = qrcode.getQrCodeImg(userInfo.inviteKey, appWhere,0);
                                    //上传图片获取媒体ID
                                    var c = WeChatCredential.Create();
                                    RemoteMedia result = WeChat.Core.ExtraCore.WeChatMediaManager.Default.Upload(new LocalMedia() { MediaPath = Server.MapPath(imguri), MediaType = Media.Image }, ak.access_token);
                                    #endregion
                                    resxml += "<MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[" + result.MediaID + "]]></MediaId></Image></xml>";
                                }
                                catch (Exception ex)
                                {
                                    WriteTxt("获取二维码,异常："+ex);
                                }
                            }
                            // 购买协议 响应
                            else if (requestXML.EventKey == "buyagreement")
                            {
                                resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[此处为 购买协议 内容！！]]></Content><FuncFlag>0</FuncFlag></xml>";
                            }
                            else { }
                        }
                        //新增关注 [requestXML.Wxevent == "subscribe"]
                        else
                        {

                            WriteTxt("进入关注！");
                            //requestXML.EventKey 有值 表示是扫描推广二维码 关注 参数为：邀请码
                            // openid 为 requestXML.FromUserName
                            #region 获取 商户信息
                            Model.sf_appidmanage appmodel = new BLL.sf_appidmanage().GetModelByNum(requestXML.ToUserName);
                            string businessNum = "", templatesNum="", appNum = appid, appSecret = secret;
                            if (appmodel!=null)
                            {
                                businessNum = appmodel.businessNum;
                                templatesNum = appmodel.templatesNum;
                                appNum = appmodel.appid;
                                appSecret = appmodel.appsecret;
                            }
                            #endregion

                            #region 获取用户基本信息
                            api.wxpay.WebClient obj = new api.wxpay.WebClient();
                            string str = obj.GetHtml(inf_uri + "grant_type=client_credential&appid=" + appNum + "&secret=" + appSecret);
                            wxaccesstoken p = api.wxpay.JsonHelper.JsonDeserialize<wxaccesstoken>(str);
                            string str2 = obj.GetHtml(info_uri + "access_token=" + p.access_token + "&openid=" + requestXML.FromUserName + "&lang=zh_CN");
                            users u = api.wxpay.JsonHelper.JsonDeserialize<users>(str2);
                            WriteTxt("成功取得用户对象！");
                            #endregion
                            //获取 关注 回执消息 配置文件
                            //IDictionary dict = ConfigurationManager.GetSection("requestStr") as IDictionary;
                            //string welcome = dict["subscribeWel"].ToString();           //欢迎语
                            //string subscribeStr = dict["subscribeStr"].ToString();      //其他说明 文字+(<a href='url'></a>)
                            //获取会员数量
                            #region 关注操作 数据库无数据 则新增用户
                            //获取参数，无邀请码 使用企业唯一的邀请码
                            BLL.sf_user_info userBll = new BLL.sf_user_info();
                            Model.sf_modeconfig configModel = new BLL.sf_modeconfig().GetModel("settingNum='" + appmodel.templatesNum+ "'");
                            string s = "";
                            //获取 商户 定义的 自动回复
                            BLL.sf_auto_reply replyBll = new BLL.sf_auto_reply();
                            Model.sf_auto_reply reply = replyBll.GetModel("isDefault=1 and " + SF.Common.Utils.getWhereByInfo(businessNum, appNum, templatesNum));
                            if (reply!=null)
                            {
                                s = reply.replyText;
                            }
                            string state = string.IsNullOrEmpty(requestXML.EventKey) ? "" : requestXML.EventKey.Replace("qrscene_", "");
                            //检测 是否存在 该openid的用户
                            //不存在 新增用户进入数据库
                            if (!userBll.ExistsByOpenId(requestXML.FromUserName))
                            {
                                WriteTxt("进入新增用户方法！");
                                state = state.Length != 6 ? "" : state;
                                Model.sf_user_info userModel = new Model.sf_user_info();
                                userModel.fatherKey = state;
                                do
                                {
                                    userModel.inviteKey = SF.Common.Utils.GetCheckCode(6);
                                } while (userBll.ExistsByKey(userModel.inviteKey));
                                do
                                {
                                    userModel.userNum = "KH"+ SF.Common.Utils.GetCheckCode(8).ToString();
                                } while (userBll.ExistsByNum(userModel.userNum));
                                userModel.busnieseNum = businessNum;
                                userModel.appNum = appNum;
                                userModel.templatesNum = configModel.settingNum;
                                userModel.sellModel = configModel.marketing_type;
                                userModel.openID = requestXML.FromUserName;
                                userModel.province = u.province;
                                userModel.city = u.city;
                                userModel.photoUri = u.headimgurl;
                                userModel.nickName = u.nickname;
                                userModel.addTime = DateTime.Now;
                                userModel.isAttention = 0;

                                long res = userBll.Add(userModel);
                                //获取推荐人 用户信息
                                string fromStr = "官方";
                                
                                if (state != "")
                                {
                                    Model.sf_user_info userFrom = userBll.GetModelByKey(state, SF.Common.Utils.getWhereByInfo(userModel.busnieseNum, userModel.appNum, userModel.templatesNum));
                                    fromStr = userFrom.nickName;
                                    //邀请关注后 自己收到一条对方已关注的信息
                                    WeChat.Core.Common.WeChatHttpHelper h = new WeChat.Core.Common.WeChatHttpHelper(sendmsg_uri);
                                    WeChatMessage data = new WeChatTextMessage() { Text = "您推荐的用户【" + userModel.nickName + "】已成功关注！", ToUser = userFrom.openID };
                                    var result = h.Post<WeChatBasicRs>(data.ToString(), new FormData { { "access_token", p.access_token } });
                                }
                                if (s!="")
                                {
                                    s = s.Replace("{0}", u.nickname);
                                    s = s.Replace("{1}", fromStr);
                                    s = s.Replace("{2}", userBll.getUserCount(SF.Common.Utils.getWhereByInfo(userModel.busnieseNum, userModel.appNum, userModel.templatesNum)).ToString());
                                }
                                else
                                {
                                    s = "欢迎您【" + u.nickname + "】，恭喜您由【" + fromStr + "】推荐成为第【" + userBll.getUserCount(SF.Common.Utils.getWhereByInfo(userModel.busnieseNum, userModel.appNum, userModel.templatesNum)) + "】位会员！";
                                }
                            }
                            //存在 修改关注状态 isAttention
                            else
                            {
                                Model.sf_user_info userInfo = new Model.sf_user_info();
                                userInfo = userBll.GetModelByOpenId(requestXML.FromUserName);
                                userInfo.isAttention = 0;
                                userInfo.nickName = u.nickname;
                                userInfo.photoUri = u.headimgurl;
                                userInfo.province = u.province;
                                userInfo.city = u.city;
                                userBll.Update(userInfo);
                                if (s != "")
                                {
                                    s = s.Replace("{0}", u.nickname);
                                    s = s.Replace("{1}", "官方");
                                    s = s.Replace("{2}", userBll.getUserCount(SF.Common.Utils.getWhereByInfo(userInfo.busnieseNum, userInfo.appNum, userInfo.templatesNum)).ToString());
                                }
                                else
                                {
                                    s = "欢迎您【" + u.nickname + "】，恭喜您再次关注本公众号！";
                                }
                            }
                            #endregion
                            resxml += "<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + s + "]]></Content><FuncFlag>0</FuncFlag></xml>";
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                WriteTxt("异常："+ex.Message);
            }
            Response.Write(resxml);
            Response.End();
        }
        /// <summary>
        /// 记录bug，以便调试
        /// </summary>
        /// 
        /// <returns></returns>
        public bool WriteTxt(string str)
        {
            try
            {
                FileStream fs = new FileStream(Server.MapPath("bugLog.txt"), FileMode.Append);
                StreamWriter sw = new StreamWriter(fs);
                //开始写入
                sw.WriteLine(str);
                //清空缓冲区
                sw.Flush();
                //关闭流
                sw.Close();
                fs.Close();
            }
            catch (Exception)
            {
                return false;
            }
            return true;
        }
        /// <summary>
        /// datetime转换为unixtime
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private int ConvertDateTimeInt(System.DateTime time)
        {
            System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
            return (int)(time - startTime).TotalSeconds;
        }
        #endregion

        protected void Button1_Click(object sender, EventArgs e)
        {
            Session[SF.Common.DTKeys.SESSION_ADMIN_INFO] = new BLL.sf_user_info().GetModel(2);
            string otid_str = "OR20150828120212560";

        }


    }
}